EXCEPTION_MAXIMUM_PARAMETERS = 15

DBG_CONTINUE			     = 00010002h
DBG_TERMINATE_THREAD		     = 40010003h
DBG_TERMINATE_PROCESS		     = 40010004h
DBG_CONTROL_C			     = 40010005h
DBG_CONTROL_BREAK		     = 40010008h
DBG_EXCEPTION_NOT_HANDLED	     = 80010001h

EXCEPTION_DEBUG_EVENT		     = 1
CREATE_THREAD_DEBUG_EVENT	     = 2
CREATE_PROCESS_DEBUG_EVENT	     = 3
EXIT_THREAD_DEBUG_EVENT 	     = 4
EXIT_PROCESS_DEBUG_EVENT	     = 5
LOAD_DLL_DEBUG_EVENT		     = 6
UNLOAD_DLL_DEBUG_EVENT		     = 7
OUTPUT_DEBUG_STRING_EVENT	     = 8
RIP_EVENT			     = 9

CONTEXT_i386 = 00010000h
CONTEXT_i486 = 00010000h
CONTEXT_CONTROL = CONTEXT_i386 OR 00000001h
CONTEXT_INTEGER = CONTEXT_i386 OR 00000002h
CONTEXT_SEGMENTS = CONTEXT_i386 OR 00000004h
CONTEXT_FLOATING_POINT = CONTEXT_i386 OR 00000008h
CONTEXT_DEBUG_REGISTERS = CONTEXT_i386 OR 00000010h
CONTEXT_FULL = CONTEXT_CONTROL OR CONTEXT_INTEGER OR CONTEXT_SEGMENTS



struct EXCEPTION_RECORD
  ExceptionCode      dd ?
  ExceptionFlags     dd ?
  ptrExceptionRecord dd ?
  ExceptionAddress   dd ?
  NumberParameters   dd ?
  ExceptionInformation rd EXCEPTION_MAXIMUM_PARAMETERS
ends

struct EXCEPTION_DEBUG_INFO
  ExceptionRecord EXCEPTION_RECORD
  dwFirstChance dd ?
ends

struct CREATE_THREAD_DEBUG_INFO
  hThread		dd  ?
  lpThreadLocalBase	dd  ?
  lpStartAddress	dd  ?
ends

struct CREATE_PROCESS_DEBUG_INFO
  hFile 		dd  ?
  hProcess		dd  ?
  hThread		dd  ?
  lpBaseOfImage 	dd  ?
  dwDebugInfoFileOffset dd  ?
  nDebugInfoSize	dd  ?
  lpThreadLocalBase	dd  ?
  lpStartAddress	dd  ?
  lpImageName		dd  ?
  fUnicode		dw  ?
ends


struct EXIT_THREAD_DEBUG_INFO
  dwExitCode  dd      ?
ends

struct EXIT_PROCESS_DEBUG_INFO
  dwExitCode  dd      ?
ends


struct LOAD_DLL_DEBUG_INFO
  hFile 		    dd	 ?
  lpBaseOfDll		    dd	 ?
  dwDebugInfoFileOffset     dd	 ?
  nDebugInfoSize	    dd	 ?
  lpImageName		    dd	 ?
  fUnicode		    dw	 ?
ends


struct UNLOAD_DLL_DEBUG_INFO
  .lpBaseOfDll	dd  ?
ends


struct OUTPUT_DEBUG_STRING_INFO
  lpDebugStringData	dd    ?
  fUnicode		dw    ?
  nDebugStringiLength	dw    ?
ends


struct RIP_INFO
  dwError  dd  ?
  dwType   dd  ?
ends


SIZE_OF_80387_REGISTERS   = 80
MAXIMUM_SUPPORTED_EXTENSION = 512

struct FLOATING_SAVE_AREA
  ControlWord	dd	?
  StatusWord	dd	?
  TagWord	dd	?
  ErrorOffset	dd	?
  ErrorSelector dd	?
  DataOffset	dd	?
  DataSelector	dd	?
  RegisterArea	rb SIZE_OF_80387_REGISTERS
  Cr0NpxState	dd	?
ends

struct CONTEXT
  ContextFlags	dd	?
  iDr0		dd	?
  iDr1		dd	?
  iDr2		dd	?
  iDr3		dd	?
  iDr6		dd	?
  iDr7		dd	?
  FloatSave	FLOATING_SAVE_AREA
  regGs 	dd	?
  regFs 	dd	?
  regEs 	dd	?
  regDs 	dd	?
  regEdi	dd	?
  regEsi	dd	?
  regEbx	dd	?
  regEdx	dd	?
  regEcx	dd	?
  regEax	dd	?
  regEbp	dd	?
  regEip	dd	?
  regCs 	dd	?
  regFlag	dd	?
  regEsp	dd	?
  regSs 	dd	?
  ExtendedRegisters rb MAXIMUM_SUPPORTED_EXTENSION
ends


struct SECURITY_ATTRIBUTES
  nLength	       dd ?
  lpSecurityDescriptor dd ?
  bInheritHandle       dd ?
ends


..TryLevel = 0

macro beginTry {
  common
    ptrExceptionContext equ esp+$0c
    ptrExceptionRecord	equ esp+$04

    local ..handler, ..endtry
    end@try equ ..endtry

  if defined ..handler
	..TryLevel = ..TryLevel+1
	pushd	..handler
	pushd	[fs:0]
	mov	[fs:0], esp
  end if

  macro onException \{
	jmp	..endtry
    ..handler:
  \}

  macro Ignore \{
	mov	eax, [ptrExceptionContext]
	mov	[eax+CONTEXT.regEip], ..endtry
	xor	eax, eax
	retn
  \{

  macro Retry \{
	xor	eax, eax
	retn
  \}


  macro Next \{
	mov	eax, 1
	retn
  \{

}


macro endTry {
  common
  label end@try
  if ..TryLevel > 0
	popd	[fs:0]
	add	esp, 4
	..TryLevel = ..TryLevel - 1
  end if
  purge onException
  purge Ignore
  purge Next
  purge Retry
  restore end@try
  restore ptrExceptionContext
  restore ptrExceptionRecord
}

